package com.swak.persistence.mybatis.methods.impls;

import com.swak.define.ColumnDefine;
import com.swak.persistence.mybatis.methods.AbstractMethod;
import com.swak.persistence.mybatis.methods.Sqls;
import com.swak.utils.StringUtils;

public class Merge extends AbstractMethod {

	@Override
	protected void doInject() {
		if (!this.supportMethod(Sqls.MERGE)) {
			return;
		}

		String sql = new StringBuilder().append(SCRIPT_START).append(this.parseSql()).append(SCRIPT_END).toString();

		this.addInsertMappedStatement(this.table.entity, Sqls.MERGE.getMethod(), sql);
	}

	protected String parseSql() {
		StringBuilder sql = new StringBuilder();
		String property = "mergeFlag";
		sql.append("<if test=\"").append(property).append(" != null\">").append(this.parsePureUpdateProperty())
				.append("</if>");
		sql.append("<if test=\"").append(property).append(" == null\">").append(this.parseReplaceProperty())
				.append("</if>");
		return sql.toString();
	}

	protected String parsePureUpdateProperty() {
		return new StringBuilder().append(UPDATE).append(SPACE).append(this.table.getName()).append(SPACE)
				.append(this.convertSet(this.parseUpdateProperty())).append(WHERE).append(SPACE)
				.append(this.parsePkEqualColumns()).toString();
	}

	protected String convertSet(String sql) {
		return SET_START + NEWLINE + sql + NEWLINE + SET_END;
	}

	protected String parseReplaceProperty() {
		return new StringBuilder().append(INSERT).append(SPACE).append(this.table.getName()).append(LEFT_BRACKET)
				.append(this.parseSqlColumns()).append(RIGHT_BRACKET).append(SPACE).append(VALUES).append(LEFT_BRACKET)
				.append(this.parseInsertSqlProperty()).append(RIGHT_BRACKET).append(SPACE).append(REPLACE).append(SPACE)
				.append(UPDATE).append(SPACE).append(this.parseUpdateProperty()).append(PADDING2).toString();
	}

	/**
	 * 解析列
	 */
	@Override
	protected String parseSqlColumns() {
		StringBuilder sql = new StringBuilder();
		for (ColumnDefine column : table.columns) {
			String name = column.name;
			sql.append(name).append(SPLIT);
		}
		sql.append(DEL_AT);
		return sql.toString();
	}

	/**
	 * insert 后面的属性值
	 * 
	 * @param <T>
	 * @param table
	 * @return
	 */
	protected String parseInsertSqlProperty() {
		StringBuilder sql = new StringBuilder();
		for (ColumnDefine column : table.columns) {
			String name = column.javaProperty;
			sql.append(HASH_LEFT_BRACE).append(name).append(RIGHT_BRACE).append(SPLIT);
		}
		sql.append(HASH_LEFT_BRACE).append(delAtProperty).append(RIGHT_BRACE);
		return sql.toString();
	}

	/**
	 * 解析修改列
	 */
	protected String parseUpdateProperty() {
		StringBuilder sql = new StringBuilder();
		for (ColumnDefine column : this.table.columns) {
			String name = column.name;
			String property = column.javaProperty;

			// 开启 stat ： 增量添加的功能
			if (!column.isPk() && !column.isCreateDate() && column.isStat()) {
				sql.append("<if test=\"").append(property).append(" != null\">").append(name).append(EQUALS)
						.append(StringUtils.format(STAT_CHECK, name, name)).append(PLUS).append(HASH_LEFT_BRACE)
						.append(property).append(RIGHT_BRACE).append(SPLIT).append("</if>");
			}

			// 开启 toggle ：将需要设置的字段设置为 0 或者 1
			else if (!column.isPk() && !column.isCreateDate() && column.isToggle()) {//
				sql.append("<if test=\"").append(property).append(" != null\">").append(name).append(EQUALS)
						.append(StringUtils.format(TOGGLE_CHECK, name, name)).append(SPLIT).append("</if>");
			}

			// 开启 max ：取大值
			else if (!column.isPk() && !column.isCreateDate() && column.isMax()) {//
				sql.append("<if test=\"").append(property).append(" != null\">").append(name).append(EQUALS)
						.append(StringUtils.format(MAX_CHECK, name, name, property, name, property)).append(SPLIT)
						.append("</if>");
			}

			// 开启 min ：取小值
			else if (!column.isPk() && !column.isCreateDate() && column.isMin()) {//
				sql.append("<if test=\"").append(property).append(" != null\">").append(name).append(EQUALS)
						.append(StringUtils.format(MIN_CHECK, name, name, property, name, property)).append(SPLIT)
						.append("</if>");
			}

			// 其他字段
			else if (!column.isPk() && !column.isCreateDate()) { // 可以修改
				sql.append("<if test=\"").append(property).append(" != null\">").append(name).append(EQUALS)
						.append(HASH_LEFT_BRACE).append(property).append(RIGHT_BRACE).append(SPLIT).append("</if>");
			}
		}
		return sql.toString();
	}
}
